package com.chang.bootplus.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.chang.bootplus.base.exception.BusException;
import com.chang.bootplus.base.utils.ApiResponse;
import com.chang.bootplus.base.utils.BeanUtil;
import com.chang.bootplus.entity.MatrixShopcart;
import com.chang.bootplus.entity.ProductCates;
import com.chang.bootplus.entity.ProductCatesDetails;
import com.chang.bootplus.mapper.ProductCatesMapper;
import com.chang.bootplus.po.ProductCatesIdPO;
import com.chang.bootplus.po.ProductCatesPO;
import com.chang.bootplus.service.ProductCatesDetailsService;
import com.chang.bootplus.service.ProductCatesService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chang.bootplus.service.ProductDetailsService;
import com.chang.bootplus.vo.ProductCatesVO;
import com.chang.bootplus.vo.ProductOfCategoryOfSonVO;
import com.chang.bootplus.vo.ProductOneCategoryDetailVO;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author chang
 * @since 2022-01-25
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ProductCatesServiceImp extends ServiceImpl<ProductCatesMapper, ProductCates> implements ProductCatesService {

    final ProductCatesDetailsService productCatesDetailsService;
    final ProductCatesMapper productCatesMapper;

    @Override
    public ApiResponse<ProductCatesVO> listProductCategory(ProductCatesIdPO po) {
        po.setPageNumber(po.getPageNumber()-1);
        List<ProductCates> productCates = productCatesMapper.listProductCategory(po);

        // 此为保存每一个分类的子分类的信息的队列
        Queue<List<ProductOfCategoryOfSonVO>> sonCatgorydetailsList = new LinkedList<>();

        productCates.stream().forEach(productCate -> {
            List<ProductOfCategoryOfSonVO> sonCatgorydetails = new ArrayList<>();
            // 递归查找子分类
            seekSonCategory(sonCatgorydetails,productCate.getId());
            sonCatgorydetailsList.offer(sonCatgorydetails);
        });

        List<ProductCatesVO> productCatesVOS = productCates.stream().map(productCate -> BeanUtil.beanA2beanB(productCate, ProductCatesVO.class)
                .setDetails(productCatesDetailsService.list(new LambdaQueryWrapper<ProductCatesDetails>()
                                .eq(ProductCatesDetails::getProCatesId, productCate.getId())).stream()
                        .map(productCatesDetails -> new ProductOneCategoryDetailVO()    //由 productCatesDetails 映射为一个新的对象
                                .setDetailMessage(productCatesDetails.getMessage()).setId(productCatesDetails.getId()))
                        .collect(Collectors.toList())).setSonCatgorydetails(sonCatgorydetailsList.poll())).collect(Collectors.toList());

        return new ApiResponse<>(productCatesVOS);
    }

    @Override
    public ApiResponse<Void> addProductCategory(ProductCatesPO po) {
        ProductCates productCates = BeanUtil.beanA2beanB(po, ProductCates.class);
        List<String> details = po.getDetails();
        boolean save = save(productCates);
        if(!save){
            throw new BusException("添加分类时失败");
        }

        ProductCates one = getOne(new LambdaQueryWrapper<ProductCates>().eq(ProductCates::getTitle, po.getTitle()));

        details.stream().forEach(detail ->{
            boolean b = productCatesDetailsService.save(new ProductCatesDetails().setMessage(detail).setProCatesId(one.getId()));
            if(!b){
                throw new BusException("添加分类详情时添加失败");
            }
        });

        return new ApiResponse().setReMsg("添加成功");
    }

    //  递归查找分类
    public void seekSonCategory(List<ProductOfCategoryOfSonVO> list,Long id){
        List<ProductCates> temp = list(new LambdaQueryWrapper<ProductCates>().eq(ProductCates::getParentId, id));
        if(temp == null){
            return;
        }

        list.addAll(temp.stream().map(productCates -> BeanUtil.beanA2beanB(productCates,ProductOfCategoryOfSonVO.class)).collect(Collectors.toList()));
        temp.stream().forEach(productCates -> {
            seekSonCategory(list,productCates.getId());
        });
    }
}
